/**
 * RefundController.java
 * 
 * Copyright@2015 OVT Inc. All rights reserved. 
 * 
 * 2015年12月22日
 */
package com.ovt.order.controller;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ovt.common.model.JsonDocument;
import com.ovt.common.utils.CollectionUtils;
import com.ovt.order.controller.response.PaymentServiceAPIResult;
import com.ovt.order.dao.contant.OrderState;
import com.ovt.order.dao.contant.DBConstants.TABLES.ALI_REFUND_LOG;
import com.ovt.order.dao.vo.AliRefundLog;
import com.ovt.order.dao.vo.Refund;
import com.ovt.order.service.OrderService;
import com.ovt.order.service.RefundLogService;
import com.ovt.order.service.RefundService;
import com.ovt.order.service.alipay.AlipayNotify;
import com.ovt.order.service.exception.ServiceErrorCode;
import com.ovt.order.service.exception.ServiceException;

/**
 * RefundController
 * 
 * @Author leo.liu
 * @Version 1.0
 * @See
 * @Since [OVT Cloud Platform]/[API] 1.0
 */
@Controller
@RequestMapping("/refund")
public class RefundController
{
    @Autowired
    private RefundService refundService;

    @Autowired
    private RefundLogService refundLogService;

    @Autowired
    private OrderService orderService;

    @RequestMapping(method = RequestMethod.POST, value = "/alinotify")
    @ResponseBody
    public String aliNotify(HttpServletRequest request)
            throws ServiceException, IOException
    {
        Map<String, String> params = AlipayNotify.processNotifyParams(request
                .getParameterMap());

        if (AlipayNotify.verify(params))
        {
            List<Long> refundRequestIds = refundService
                    .getRefundRequestIdsByBatchNo(params
                            .get(ALI_REFUND_LOG.BATCH_NO));
            
            //check notify params
            checkAlipayRefundNotifyParams(params, refundRequestIds.size());

            // save alipay refund log
            long refundLogId = refundLogService.saveAliRefundLog(params);

            // update refunds
            List<Refund> refunds = refundService
                    .parseAlipayRefundNotifyParams(params);
            if (CollectionUtils.isNotEmpty(refunds))
            {
                for (Refund refund : refunds)
                {
                    refund.setRefundLogId(refundLogId);
                }
            }

            refundService.updateRefunds(refunds);

            // update refund request state
            orderService.setRefundRequestListState(refundRequestIds,
                    OrderState.REFUND_DONE);

            return JsonDocument.STATE_SUCCESS;
        }
        else
        {
            return JsonDocument.STATE_FAILED;
        }

    }

    @RequestMapping(method = RequestMethod.GET, value = "/list")
    @ResponseBody
    public JsonDocument getRefundList() throws ServiceException
    {
        List<Refund> refundList = refundService.getRefundList();

        return new PaymentServiceAPIResult(refundList);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/log/list")
    @ResponseBody
    public JsonDocument getAliRefundLogList() throws ServiceException
    {
        List<AliRefundLog> aliRefundLogList = refundLogService
                .getAliRefundLogList();

        return new PaymentServiceAPIResult(aliRefundLogList);
    }

    private void checkAlipayRefundNotifyParams(Map<String, String> params,
            int totalRefundNumofBatch) throws ServiceException
    {
        long successNum = Long.valueOf(params.get(ALI_REFUND_LOG.SUCCESS_NUM));

        if (totalRefundNumofBatch <= 0)
        {
            throw new ServiceException(
                    ServiceErrorCode.INVALID_REFUND_BATCH_NO,
                    "Invalid alipay refund batch no");
        }

        if (successNum > totalRefundNumofBatch || successNum < 0)
        {
            throw new ServiceException(
                    ServiceErrorCode.INVALID_REFUND_SUCCESS_NUM,
                    "Invalid alipay refund success num");
        }
        
        if(successNum < totalRefundNumofBatch)
        {
            //output failed refund
        }
    }
}
